package org.richin.net.HTML.util;

import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.richin.lang.util.StringUtils;
import org.richin.net.HTML.util.HTMLParser;

/**
 * @author jacky
 * @version $Id: HtmlUtils.java,v 0.1 2008-7-9 上午10:01:22 jacky Exp $
 */
public final class HtmlUtils {

	private static final Log logger = LogFactory.getLog(HtmlUtils.class);

	private static final Pattern scriptTag = Pattern.compile("(?i)(?s)(<script.+?</script>)|( on.+?=)");
	private static final Pattern pattern = Pattern.compile("(\\<[^>]*\\>)|(\\&nbsp;)|(\n)");
	private static final String emptyString = "";

	/**
	 * HTML字符过滤,进行过滤的五个字符为'<','>','"','&','''
	 * @param str 需要过滤的字符串
	 * @return 过滤后的字符串
	 */
	public static String escape(String str) {
		if (StringUtils.isEmpty(str)) {
			return str;
		}
		StringBuilder result = null;
		for (int i = 0; i < str.length(); i++) {
			String filtered = null;
			switch (str.charAt(i)) {
			case '<':
				filtered = "&lt;";
				break;
			case '>':
				filtered = "&gt;";
				break;
			case '&':
				filtered = "&amp;";
				break;
			case '"':
				filtered = "&quot;";
				break;
			case '\'':
				filtered = "&#39;";
				break;
			}

			if (result == null) {
				if (filtered != null) {
					result = new StringBuilder(str.length() + 50);
					if (i > 0) {
						result.append(str.substring(0, i));
					}
					result.append(filtered);
				}
			} else {
				if (filtered == null) {
					result.append(str.charAt(i));
				} else {
					result.append(filtered);
				}
			}
		}
		return (result == null) ? str : result.toString();
	}

	/**
	 *
	 * 完全清除所有HTML代码,空格与换行符
	 * @param str 需要清除的字符串
	 * @return 清除后的字符串
	 */
	public static String filter(String str) {
		if (StringUtils.isEmpty(str))
			return str;
		return pattern.matcher(str).replaceAll("");
		//		value = value.replaceAll("(\\<[^>]*\\>)", "");// 过滤掉所有<>之间的标签
		//		value = value.replaceAll("(\\&nbsp;)", "");// 过滤掉所有&nbsp;标签;
		//		return value.replaceAll("\n", "");
	}

	/**
	 * 去掉禁止输入的html标签,比如说script等
	 * 
	 * @param s
	 * @return
	 */
	public static final String escapeForbiddenHtml(String s) {
		return escapeScriptTag(s);
	}

	/**
	 * 去掉禁止输入的script标签,以及 onclick这样的函数
	 * 
	 * @param s
	 * @return
	 */
	public static final String escapeScriptTag(String s) {
		if (s == null) {
			return null;
		}
		Matcher m = scriptTag.matcher(s);
		return m.replaceAll(emptyString);
	}

	/**
	 * 得到去除html标签后的文字
	 * 
	 * @param s
	 * @return
	 */
	public static final String parseHtml(String s) {
		if (s == null) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		try {
			Reader r = new StringReader(s);
			HTMLParser parser = new HTMLParser(r);
			LineNumberReader reader = new LineNumberReader(parser.getReader());
			for (String l = reader.readLine(); l != null; l = reader.readLine()) {
				sb.append(l);
			}
			r.close();
		} catch (IOException e) {
			logger.error("error than parse html string", e);
		}
		return sb.toString();
	}

	/**
	 * 得到去除html标签后的文字
	 * 
	 * @param s
	 * @param maxLength
	 *            最大长度,
	 * @return s.length <= maxLength
	 */
	public static final String parseHtml(String s, int maxLength) {
		if (maxLength <= 0) {
			throw new java.lang.IllegalArgumentException("maxLength must greate than zero");
		}
		if (s == null) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		try {
			Reader r = new StringReader(s);
			HTMLParser parser = new HTMLParser(r);
			LineNumberReader reader = new LineNumberReader(parser.getReader());
			for (String l = reader.readLine(); l != null; l = reader.readLine()) {
				sb.append(l);
				if (sb.length() >= maxLength) {
					break;
				}
			}
			r.close();
		} catch (IOException e) {
			logger.error("error than parse html string", e);
		}
		if (sb.length() >= maxLength) {
			return sb.substring(0, maxLength);
		}
		return sb.toString();
	}
}
